package com.study.web.handler;

import com.study.common.exception.BizException;
import com.study.common.response.ResponseEntity;
import com.study.common.response.ResponseWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * @Package com.study.web.handler
 * @ClassName: BizExceptionHandler
 * @Description: 统一异常处理类
 * @author yaojinshan
 * @date 2018年12月4日 下午3:46:35
 * @version 1.0
 */
@ControllerAdvice
public class BizExceptionHandler implements ResponseBodyAdvice<Object> {
    static Logger logger = LoggerFactory.getLogger(BizExceptionHandler.class);
	/**
	* @Title: bindException
	* @Description: 用于处理@Validated校验参数异常
	* @param be
	* @return   
	* @return String 
	* @author yaojinshan
	* @date 2018年12月4日 下午5:38:08
	* @throws
	 */
	@ExceptionHandler(BindException.class)
	@ResponseBody
	public String bindException(BindException be) {
		BindingResult bindingResult = be.getBindingResult();
		String errorMesssage = "";
		for (FieldError fieldError : bindingResult.getFieldErrors()) {
			errorMesssage += fieldError.getField() + ":" + fieldError.getDefaultMessage() + ", ";
		}
		if(errorMesssage.length() > 0){
			errorMesssage = errorMesssage.substring(0, errorMesssage.length() - 2);
		}
		return ResponseWriter.execption(errorMesssage, null);
	}
	
	/**
	* @Title: methodArgumentNotValidException
	* @Description: 用于处理方法参与不通过校验异常
	* @param be
	* @return   
	* @return String 
	* @author yaojinshan
	* @date 2018年12月4日 下午5:42:00
	* @throws
	 */
	@ExceptionHandler(MethodArgumentNotValidException.class)
	@ResponseBody
	public String methodArgumentNotValidException(MethodArgumentNotValidException be) {
		BindingResult bindingResult = be.getBindingResult();
		String errorMesssage = "";
		for (FieldError fieldError : bindingResult.getFieldErrors()) {
			errorMesssage += fieldError.getField() + ":" + fieldError.getDefaultMessage() + ", ";
		}
		if(errorMesssage.length() > 0){
			errorMesssage = errorMesssage.substring(0, errorMesssage.length() - 2);
		}
		return ResponseWriter.execption(errorMesssage, null);
	}

	/**
	* @Title: missingServletRequestParameterException
	* @Description: 用于处理@RequestParam校验参数异常
	* @param msrp
	* @return   
	* @return String 
	* @author yaojinshan
	* @date 2018年12月4日 下午5:25:54
	* @throws
	 */
	@ExceptionHandler(MissingServletRequestParameterException.class)
	@ResponseBody
	public String missingServletRequestParameterException(MissingServletRequestParameterException msrp) {
		String message = msrp.getMessage();
		return ResponseWriter.execption(message, null);
	}

	/**
	 * @Title: BizException
	 * @Description: 用于处理业务异常
	 * @param bz
	 * @return   
	 * @return String 
	 * @author yaojinshan
	 * @date 2018年12月4日 下午5:25:54
	 * @throws
	 */
	@ExceptionHandler(BizException.class)
	@ResponseBody
	public String bizException(BizException bz) {
		String message = bz.getMessage();
		return ResponseWriter.execption(message, null);
	}
	
	/**
	* @Title: exception
	* @Description: 用于处理所有未知异常
	* @param e
	* @return   
	* @return String 
	* @author yaojinshan
	* @date 2018年12月4日 下午5:35:56
	* @throws
	 */
	@ExceptionHandler(Exception.class)
	@ResponseBody
    public String exception(Exception e){
		return ResponseWriter.execption("系统处理异常，请退出后重试！", null);
    }

    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        logger.debug("MyResponseBodyAdvice==>supports:" + converterType);
        logger.debug("MyResponseBodyAdvice==>supports:" + returnType.getClass());
        logger.debug("MyResponseBodyAdvice==>supports:" + MappingJackson2HttpMessageConverter.class.isAssignableFrom(converterType));
        return MappingJackson2HttpMessageConverter.class.isAssignableFrom(converterType);
    }
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
                                  ServerHttpResponse response) {
        if (body == null) {
            ResponseEntity responseEntity = new ResponseEntity("200","操作成功",null);
            body = responseEntity;
        }
        return body;
    }
}
